#pragma once
#include <afxsock.h>
class NetNode;
#include "Board.h"
#include <vector>
using std::vector;
#include <string>
using std::string;

const static int TCP_PORT = 1080;
const static int PACK_LENGTH = 256;

#define	COMMAND_SOF			0x1ACFFC1D
#define OP_TARGET_EEPROM	0x00
#define OP_TARGET_IIC		0x01
#define OP_TARGET_RS485A	0x02
#define OP_TARGET_RS485B	0x03
#define	OP_RESET			0x04

#define COMMAND_WRITE		0x01
#define COMMAND_READ		0x00

class PERFORMANCE_COUNTER
{
private:
	LARGE_INTEGER CurrentTickCount_;
	LARGE_INTEGER OldTickCount_;
	LARGE_INTEGER TickFrquency_;
	double EllapsedTime_;
	double TotalTime_;
public:
	PERFORMANCE_COUNTER():
	  EllapsedTime_(0.0),
		  TotalTime_(0.0)
	  {
		  ::QueryPerformanceFrequency(&TickFrquency_);
		  ::QueryPerformanceCounter(&CurrentTickCount_);
		  OldTickCount_ = CurrentTickCount_;
	  }

	  void RESET(const double intial_time = 0.0)
	  {
		  TotalTime_ = intial_time;
		  EllapsedTime_ = intial_time;
		  ::QueryPerformanceCounter(&CurrentTickCount_);
		  OldTickCount_ = CurrentTickCount_;
	  }
	  void CALCULATE_ELLAPSED_TIME()
	  {
		  ::QueryPerformanceCounter(&CurrentTickCount_);
		  EllapsedTime_ = (double)(CurrentTickCount_.QuadPart - OldTickCount_.QuadPart)/TickFrquency_.QuadPart;
		  TotalTime_ += EllapsedTime_;
		  OldTickCount_ = CurrentTickCount_;
	  }
	  void CALCULATE_ELLAPSED_TIME(const PERFORMANCE_COUNTER& to_intialize)
	  {
		  CurrentTickCount_ = to_intialize.CURRENT_TICK_COUNT();
		  EllapsedTime_ = (double)(CurrentTickCount_.QuadPart - OldTickCount_.QuadPart)/TickFrquency_.QuadPart;
		  TotalTime_ += EllapsedTime_;
		  OldTickCount_ = CurrentTickCount_;
	  }
	  const LARGE_INTEGER& CURRENT_TICK_COUNT() const {return CurrentTickCount_;}


	  double ELLAPSED_MILLISECONDS() const {return EllapsedTime_ * 1000;}
	  double ELLAPSED_SECONDS() const {return EllapsedTime_;}
	  double TOTAL_TIME() const {return TotalTime_;}
};

class ProtocalHelper : public CAsyncSocket
{
public:
	ProtocalHelper(void);
	~ProtocalHelper(void);
	void get_node_state(NetNode* pNode);
	bool modify_ip( DWORD newIP );
	void modify_mac( CString newmac );
	void modify_type( CString newtype );
	void set_board_text( unsigned char slot_num, Board * bd, TEXT_INFO info );
	void set_text_info(  unsigned char slot_num, unsigned char base, DIMENSION info );
	void set_board_time( unsigned char slot_num, Board * bd, TIME_INFO info );
	void write_iic(int addr, unsigned char* data, int len);
	void reset(unsigned char slot_num);
	void send_short_cmd(unsigned char slot_num, unsigned char* cmd, int len = 8);
	bool is_connected();
	bool connect( );
	bool finished();
	void keep_send();
protected:
	virtual void OnReceive(int nErrorCode);
	virtual void OnSend(int nErrorCode);
	virtual void OnOutOfBandData(int nErrorCode);
	virtual void OnAccept(int nErrorCode);
	virtual void OnConnect(int nErrorCode);
	virtual void OnClose(int nErrorCode);
	virtual int Send(const void* lpBuf, int nBufLen, int nFlags = 0);

private:
	ProtocalHelper(const ProtocalHelper& rSrc);    // no implementation
	void operator=(const ProtocalHelper& rSrc);  // no implementation
	NetNode * m_node;
	void send_pack(char * data, int length);
	vector<string> m_unsent;
	bool m_connected;
	bool m_remoteReady;
	bool m_timeOut;
	bool m_sentAPack;
	bool m_threadRunning;
//	char tBuf[PACK_LENGTH];
	const static int CMD_LEN = 8;
	PERFORMANCE_COUNTER m_cnt;
	CWinThread * m_threadSend;
};

